#include <iostream>
#include <string>
#include <vector>
#include <assert.h>
#include "../logs/bitlog.hpp"
using std::cout, std::endl;


void testUtil(){
    // std::string name = "./TestRollDir/TestRoll.log";
    // cout << mylog::Util::FileUtil::Path(name) << endl;
    // mylog::Util::FileUtil::CreateDir("./TestRollDir");
}

void testLevel(){
    // cout << mylog::LogLevel::toString(mylog::LogLevel::value::UNKNOWN) << endl;
    // cout << mylog::LogLevel::toString(mylog::LogLevel::value::DEBUG) << endl;
    // cout << mylog::LogLevel::toString(mylog::LogLevel::value::INFO) << endl;
    // cout << mylog::LogLevel::toString(mylog::LogLevel::value::WARNING) << endl;
    // cout << mylog::LogLevel::toString(mylog::LogLevel::value::ERROR) << endl;
    // cout << mylog::LogLevel::toString(mylog::LogLevel::value::FATAL) << endl;
    // cout << mylog::LogLevel::toString(mylog::LogLevel::value::OFF) << endl;
}

void testMsg(){
    // mylog::LogMsg log("root", mylog::LogLevel::value::DEBUG, __FILE__, __LINE__, "For Test");
    // cout << log._file << endl;
    // cout << log._line << endl;
    // cout << log._name << endl;
    // cout << log._payload << endl;
    // cout << mylog::LogLevel::toString(log._level) << endl;
    // cout << log._time << endl;
}

void testFormat(){
    // mylog::LogMsg log("root", mylog::LogLevel::value::DEBUG, __FILE__, __LINE__, "For Test");
    // mylog::Formatter fmt;
    // cout << fmt.Format(log) << endl;
}

void testSkin(){
    // mylog::LogMsg log("root", mylog::LogLevel::value::DEBUG, __FILE__, __LINE__, "For Test");
    // mylog::Formatter fmt;
    // std::string deta = fmt.Format(log);
    // std::vector<mylog::LogSink::ptr> arry;
    // arry.push_back(mylog::SkinFactory::Build<mylog::StdSkin>());
    // arry.push_back(mylog::SkinFactory::Build<mylog::FileSink>("TestFileSink.log"));
    // arry.push_back(mylog::SkinFactory::Build<mylog::RollSink>("./TestRollDir2/TestRoll", 1024));

    // size_t size = 0;
    // for(; size < 1024 * 100; size += deta.size()){
    //     arry[2]->Log(deta.c_str(), deta.size());
    //     sleep(1);
    //     cout << "完成一次\n";
    // }
}


void LoggerTest(const std::string &logger_name) {
    mylog::Logger::ptr lp = mylog::GetLogger(logger_name);
    assert(lp.get());
    LOGF("------------example--------------------");
    lp->Debug("%s", "logger->debug");
    lp->Info("%s", "logger->info");
    lp->Warning("%s", "logger->warn");
    lp->Error("%s", "logger->error");
    lp->Fatal("%s", "logger->fatal");
    LOG_DEBUG(lp, "%s", "LOG_DEBUG");
    LOG_INFO(lp, "%s", "LOG_INFO");
    LOG_WARNING(lp, "%s", "LOG_WARN");
    LOG_ERROR(lp, "%s", "LOG_ERROR");
    LOG_FATAL(lp, "%s", "LOG_FATAL");
    LOGF("---------------------------------------");
    
    std::string log_msg = "hello";
    size_t fsize = 0;
    size_t count = 0;
    while(count < 100000) {
        std::string msg = log_msg + std::to_string(count++);
        lp->Error("%s", msg.c_str());
    }
}
void FunctionalTest() {
    mylog::GlobalLoggerBuilder::ptr lbp(new mylog::GlobalLoggerBuilder);
    lbp->SetName("all_sink_logger");
    lbp->SetFormatter("[%d][%c][%f:%l][%p] %m%n");
    lbp->SetLevel(mylog::LogLevel::value::DEBUG);
    lbp->SetSinks<mylog::StdSink>();
    lbp->SetSinks<mylog::FileSink>("./logs/sync.log");
    lbp->SetSinks<mylog::RollSink>("./logs/roll-", 1024 * 1024);
    lbp->SetType(mylog::Logger::Type::LOGGER_ASYNC);
    lbp->Build(); 
    LoggerTest("all_sink_logger");
}

int main(){
    //testUtil();
    //testLevel();
    //testMsg();
    //testFormat();
    //testSkin();
    FunctionalTest();
    return 0;
}